package mesweb.mesweb.Utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import mesweb.mesweb.entity.MesTechnologyFlow;
import mesweb.mesweb.service.impl.MesTechnologyFlowServiceImpl;
import mesweb.mesweb.service.impl.MesTechnologyFlowTypeServiceImpl;
import org.apache.commons.lang3.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Json字符串工具类
 *
 * @author yanwei
 * remind：所有顶级菜单的pid为0才能正常迭代出对应的树
 */


@Component
public class MesTechnologyFlowJsonTree {

    @Autowired
    private MesTechnologyFlowServiceImpl mesTechnologyFlowService;
    @Autowired
    private MesTechnologyFlowTypeServiceImpl mesTechnologyFlowTyxpeService;
    private   static  List<MesTechnologyFlow> mesTechnologyFlows;
    private   static MesTechnologyFlowJsonTree jsonTree;

    @PostConstruct
    private void init()
    {
        jsonTree = this;
    }

    //单个分支的json
    private  static  List<MesTechnologyFlowTreeNode> getRootNodes(Long rootId) {
        List<MesTechnologyFlowTreeNode> treeNodeList = new ArrayList<>();
        if(rootId != 0)
        {
            QueryWrapper<MesTechnologyFlow> mesTechnologyFlowQueryWrapper = new QueryWrapper<>();
            mesTechnologyFlowQueryWrapper.eq("technology_Flow_Type_Id",rootId);
            mesTechnologyFlows = jsonTree.mesTechnologyFlowService.list(mesTechnologyFlowQueryWrapper);
        }
        else {
            mesTechnologyFlows = jsonTree.mesTechnologyFlowService.list();
        }
        for (MesTechnologyFlow itm : mesTechnologyFlows
        ) {
            List<MesTechnologyFlowTreeNode> optionalMesTechnologyFlowTreeNode = treeNodeList.stream().filter(
                    o->o.getMesTechnologyFlow().getId().equals(itm.getTechnologyFlowTypeId())
            ).collect(Collectors.toList());
            if (optionalMesTechnologyFlowTreeNode != null && optionalMesTechnologyFlowTreeNode.size()>0) {
                optionalMesTechnologyFlowTreeNode.get(0).getChildren().add(itm);
            } else {
                MesTechnologyFlowTreeNode mesTreeNode = new MesTechnologyFlowTreeNode();
                MesTechnologyFlow clone = (MesTechnologyFlow)SerializationUtils.clone(itm);
                clone.setId(itm.getTechnologyFlowTypeId());
                clone.setParentId(-1L);
                clone.setTechnologyFlowName(jsonTree.mesTechnologyFlowTyxpeService.getById(itm.getTechnologyFlowTypeId()).getTechnologyFlowTypeName());
                mesTreeNode.setMesTechnologyFlow(clone);
                List<MesTechnologyFlow> lst = new ArrayList<>();
                lst.add(itm);
                mesTreeNode.setChildren(lst);
                treeNodeList.add(mesTreeNode);
            }
        }
        return treeNodeList;
    }

    public static String Tree(Long rootId) throws Exception {
        List<MesTechnologyFlowTreeNode> treeNodes = getRootNodes(rootId);
        StringBuilder sb = new StringBuilder();
        MesTechnologyFlow root = new MesTechnologyFlow();
        root.setId(-1L);
        root.setParentId(-1L);
        root.setTechnologyFlowName("全部");
        root.setTechnologyFlowNo("reserve");
        root.setDescription("reserve");
        root.setTechnologyFlowTypeId(-1L);
        String jsonRoot = JSON.toJSONString(root, SerializerFeature.WriteMapNullValue);

       // sb.append("{\"id\": -1,\"name\":\"全部\",\"children\":[");
        sb.append(jsonRoot.replaceAll("\"","\\\\\""));
        sb.deleteCharAt(sb.length()-1).append(",\"children\":[");
        if(treeNodes.size()>0) {
            for (MesTechnologyFlowTreeNode itm : treeNodes
            ) {
                StringBuilder stringBuilder = new StringBuilder();
                String jsonNode = JSON.toJSONString(itm.getMesTechnologyFlow(),SerializerFeature.WriteMapNullValue);
                String newJsonNode = jsonNode.replaceAll("\"","\\\\\"");
                sb.append(newJsonNode).deleteCharAt(sb.length()-1).append(",\"children\":[");
                sb.append(treeJson(0, itm.getChildren(), stringBuilder, "ParentId", "id", "TechnologyFlowName"));
                sb.append("]},");
            }
            sb.deleteCharAt(sb.length() - 1);
        }
        sb.append("]}");
        return sb.toString();
    }

    /**
     * 根据id,pid和树要显示的属性生成树的Json字符串 ,字符串没有中括号，因为牵扯递归调用，不方便处理
     *
     * @param
     * @param objs
     * @param pidAttr
     * @param idAttr
     * @return
     * @throws Exception
     */
    public  static  String treeJson(long pid, List objs, StringBuilder builder, String pidAttr,
                           String idAttr, String name) throws Exception {
        if (objs == null || objs.size() == 0) {
            return "{\"children\":[]}";
        }
        for (Iterator iter = objs.iterator(); iter.hasNext(); ) {
            MesTechnologyFlow t = (MesTechnologyFlow)iter.next();
            long id = t.getId();// getLong(t, idAttr);
            long temp_pid = t.getParentId();// getLong(t, pidAttr);
            String label = t.getTechnologyFlowName();// getValue(t, name);
            if (pid == Long.MAX_VALUE) {
                break;
            }
            if (temp_pid == pid) {
                 String jsonNode = JSON.toJSONString(t,SerializerFeature.WriteMapNullValue);
                String newJsonNode = jsonNode.substring(0,jsonNode.length()-1).replaceAll("\"","\\\\\"");
                builder.append(newJsonNode).append(",");
                if (isHasChildren(id, objs, pidAttr)) {
                    builder.append("\"children\":[");
                    treeJson(id, objs, builder, pidAttr, idAttr, name);
                    builder.append("]},");
                } else {
                    builder.append("\"children\":[");
                    builder.append("],");
                    builder.deleteCharAt(builder.length() - 1).append("},");
                }
            }
        }
        if (builder.length() >= 1) {
            builder.deleteCharAt(builder.length() - 1);
        }
        return builder.toString();
    }

    // 该方法给定一个id，一个list，判断是否包含子节点
    private  static  boolean isHasChildren(long id, List<MesTechnologyFlow> objs, String pidAttr) throws Exception {
        for (MesTechnologyFlow t : objs) {
            long pid = t.getParentId();// getLong(t, pidAttr);
            if (pid == id) {
                return true;
            }
        }
        return false;
    }

    //利用反射，执行对象的方法，获取值
    private static  long getLong(MesTechnologyFlow t, String attrName) throws Exception {
        Field[] lstF = t.getClass().getDeclaredFields();
        Field field = t.getClass().getDeclaredField(attrName);
        if (!field.isAccessible()) {
            field.setAccessible(true);
        }
        Object value = field.get(t);
        if (value == null) {
            return Long.MAX_VALUE;
        } else {
            return Long.parseLong(value.toString());
        }
    }

    //获取属性值，一般属性
    private static  String getValue(MesTechnologyFlow t, String attrName) throws Exception {
        Field field = t.getClass().getDeclaredField(attrName);
        if (!field.isAccessible()) {
            field.setAccessible(true);
        }
        Object value = field.get(t);
        if (value == null) {
            return "\"\"";
        } else {
            return value.toString();
        }
    }
}
